namespace Terra.Core.Common.ErrorCodes.Extensions;

using Terra.Core.Common.ErrorCodes.Models;
using Terra.Core.Common.Exceptions;

/// <summary>
/// 错误码扩展方法
/// </summary>
public static class ErrorCodeExtensions
{
    /// <summary>
    /// 抛出业务异常
    /// </summary>
    /// <param name="errorInfo">错误码信息</param>
    /// <param name="parameters">错误参数</param>
    public static void ThrowBusinessException(this ErrorCodeInfo errorInfo, object parameters = null)
    {
        if (parameters != null)
        {
            errorInfo.Parameters = parameters.GetType()
                .GetProperties()
                .ToDictionary(p => p.Name, p => p.GetValue(parameters));
        }

        throw new BusinessException(errorInfo.FormatMessage(), errorInfo.Code);
    }

    /// <summary>
    /// 抛出验证异常
    /// </summary>
    /// <param name="errorInfo">错误码信息</param>
    /// <param name="parameters">错误参数</param>
    public static void ThrowValidationException(this ErrorCodeInfo errorInfo, object parameters = null)
    {
        if (parameters != null)
        {
            errorInfo.Parameters = parameters.GetType()
                .GetProperties()
                .ToDictionary(p => p.Name, p => p.GetValue(parameters));
        }

        var errors = new Dictionary<string, string[]>
        {
            { "ValidationError", new[] { errorInfo.FormatMessage() } }
        };

        throw new ValidationException(errorInfo.FormatMessage(), errors);
    }

    /// <summary>
    /// 将错误码信息转换为错误响应
    /// </summary>
    /// <param name="errorInfo">错误码信息</param>
    /// <returns>错误响应</returns>
    public static ErrorResponse ToErrorResponse(this ErrorCodeInfo errorInfo)
    {
        return new ErrorResponse
        {
            Code = errorInfo.Code,
            Message = errorInfo.Message,
            Severity = errorInfo.Severity
        };
    }

    /// <summary>
    /// 将错误码信息转换为错误响应
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    /// <param name="errorInfo">错误码信息</param>
    /// <param name="data">附加数据</param>
    /// <returns>错误响应</returns>
    public static ErrorResponse<T> ToErrorResponse<T>(this ErrorCodeInfo errorInfo, T data)
    {
        return new ErrorResponse<T>
        {
            Code = errorInfo.Code,
            Message = errorInfo.Message,
            Severity = errorInfo.Severity,
            Data = data
        };
    }

    /// <summary>
    /// 格式化错误码信息
    /// </summary>
    /// <param name="errorInfo">错误码信息</param>
    /// <param name="args">格式化参数</param>
    /// <returns>格式化后的错误码信息</returns>
    public static ErrorCodeInfo Format(this ErrorCodeInfo errorInfo, params object[] args)
    {
        if (args == null || args.Length == 0)
        {
            return errorInfo;
        }

        return new ErrorCodeInfo
        {
            Code = errorInfo.Code,
            Message = string.Format(errorInfo.Message, args),
            Description = errorInfo.Description,
            Type = errorInfo.Type,
            Severity = errorInfo.Severity,
            Solution = errorInfo.Solution,
            Parameters = errorInfo.Parameters
        };
    }
}